<template>
  <div class="cluster-detail">
    <el-tabs v-show="!showNodeRebootContainer && !showNodeContainer" v-model="activeName" @tab-click="handleClick">
      <el-tab-pane label="资源列表" name="first">
        <el-table
          v-loading="listLoading"
          :data="list"
          element-loading-text="Loading"
          fit
          highlight-current-row>
          <el-table-column align="center" label="节点ID" width="95">
            <template slot-scope="scope">
              {{ scope.row.nodeId }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="机器类型">
            <template slot-scope="scope">
              {{ scope.row.machineType }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="cpu总数">
            <template slot-scope="scope">
              {{ scope.row.cpu.total }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="cpu剩余">
            <template slot-scope="scope">
              {{ scope.row.cpu.left }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="gpu总数">
            <template slot-scope="scope">
              {{ scope.row.gpu.total }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="gpu剩余">
            <template slot-scope="scope">
              {{ scope.row.gpu.left }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="gpu隔离">
            <template slot-scope="scope">
              {{ scope.row.gpu.unavailable ? scope.row.gpu.unavailable : '-' }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="内存总数">
            <template slot-scope="scope">
              {{ scope.row.mem.total }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="内存剩余">
            <template slot-scope="scope">
              {{ scope.row.mem.left }}
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center">
            <template slot-scope="scope">
              <a class="table-action" @click="viewNodeContainer(scope.row.nodeId)">查看容器</a>
              <a class="table-action" @click="clickDeleteNode(scope.row)">删除</a>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane label="监控面板" name="second">
        <iframe :src="`https://112.31.12.178:5443/grafana/dashboard/db/pai_nodeview?var-node=${curCluster.ip}&refresh=30s&orgId=1`" class="grafana-iframe" frameborder="0" />
      </el-tab-pane>
      <el-tab-pane label="K8s面板" name="third">
        <iframe :src="`https://112.31.12.178:5443/kubernetes-dashboard`" class="grafana-iframe" frameborder="0" />
      </el-tab-pane>
      <el-tab-pane label="重启面板" name="four">
        <el-date-picker
          v-model="dateRange"
          type="datetimerange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          @change="_fetchNodeRebootData()" />
        <el-table
          v-loading="listLoading"
          :data="nodeRebootList"
          element-loading-text="Loading"
          fit
          highlight-current-row>
          <el-table-column align="center" label="节点ID">
            <template slot-scope="scope">
              {{ scope.row.instance }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="重启时间">
            <template slot-scope="scope">
              {{ scope.row.start ? new Date(scope.row.start * 1000).Format("yyyy-MM-dd hh:mm:ss") : '-' }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="恢复时间">
            <template slot-scope="scope">
              {{ scope.row.end ? new Date(scope.row.end * 1000).Format("yyyy-MM-dd hh:mm:ss") : '-' }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="容器数量">
            <template slot-scope="scope">
              {{ scope.row.containers.length }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="250" align="center">
            <template slot-scope="scope">
              <a :class="{'not-allowed': scope.row.containers.length === 0}" class="table-action" @click="viewContainer(scope.row)">查看容器</a>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane name="five">
        <span slot="label">僵尸容器 <i v-show="activeName === 'five' && loadingZoombie" class="el-icon-loading" /></span>
        <el-table
          v-loading="listLoading"
          :data="zombiesContainer"
          element-loading-text="Loading"
          fit
          highlight-current-row>
          <el-table-column align="center" label="节点ID">
            <template slot-scope="scope">
              {{ scope.row.id }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="容器名称">
            <template slot-scope="scope">
              {{ scope.row.container_name }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="GPU类型">
            <template slot-scope="scope">
              {{ scope.row.gpu_type }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="GPU Info">
            <template slot-scope="scope">
              {{ scope.row.container_gpu_info }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="镜像名">
            <template slot-scope="scope">
              {{ scope.row.image_name }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="任务名称">
            <template slot-scope="scope">
              {{ scope.row.job_name }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="任务状态">
            <template slot-scope="scope">
              {{ scope.row.job_status }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="用户名">
            <template slot-scope="scope">
              {{ scope.row.username }}
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
    </el-tabs>
    <div v-show="showNodeContainer">
      <div class="container-header">
        <a class="click" @click="returnBack"><i class="el-icon-back" />返回</a>
      </div>
      <el-table
        v-loading="listLoading"
        :data="nodeContainerList"
        element-loading-text="Loading"
        fit
        highlight-current-row>
        <el-table-column align="left" label="容器名">
          <template slot-scope="scope">
            {{ scope.row.container_name }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="任务名">
          <template slot-scope="scope">
            {{ scope.row.job_name }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="GPU Info" width="100">
          <template slot-scope="scope">
            {{ scope.row.container_gpu_info }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="任务状态" width="100">
          <template slot-scope="scope">
            {{ scope.row.job_status }}
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div v-show="showNodeRebootContainer">
      <div class="container-header">
        <a class="click" @click="returnBack"><i class="el-icon-back" />返回</a>
      </div>
      <el-table
        :data="nodeRebootContainerList"
        fit
        highlight-current-row>
        <el-table-column align="left" label="任务名">
          <template slot-scope="scope">
            {{ scope.row.jobname }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="用户名">
          <template slot-scope="scope">
            {{ scope.row.usrname }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="重启时间">
          <template slot-scope="scope">
            {{ scope.row.start ? new Date(scope.row.start * 1000).Format("yyyy-MM-dd hh:mm:ss") : '-' }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="恢复时间">
          <template slot-scope="scope">
            {{ scope.row.end ? new Date(scope.row.end * 1000).Format("yyyy-MM-dd hh:mm:ss") : '-' }}
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import { getClusterNodes, getNodeReboot, getNodeContainer, getZombiesContainer, getContainerNodeList } from '@/api/cluster'

export default {
  name: 'Dashboard',
  data() {
    return {
      listLoading: true,
      activeName: 'first',
      list: [],
      nodeRebootList: [],
      nodeRebootContainerList: [],
      nodeContainerList: [],
      zombiesContainer: [],
      dateRange: [],
      showNodeRebootContainer: false,
      showNodeContainer: false,
      containerNodeList: [],
      loadingZoombie: false
    }
  },
  computed: {
    ...mapGetters([
      'curCluster'
    ])
  },
  created() {
    this._fetchData()
    this.setNodeRebootTime()
  },
  methods: {
    handleClick(val) {
      if (val.name === 'first') {
        this._fetchData()
      } else if (val.name === 'four') {
        this.setNodeRebootTime()
        this._fetchNodeRebootData()
      } else if (val.name === 'five') {
        this._fetchContainerNodeListData()
      }
    },
    // 点击删除集群资源（节点）
    clickDeleteNode(row) {
      this.$confirm('此操作将删除该资源, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this._deleteCluster(row)
      })
    },
    // 设置重启面板查询默认时间
    setNodeRebootTime() {
      const end = new Date()
      let start = new Date()
      start.setTime(end.getTime() - 3600 * 1000 * 24)
      start = new Date(start)
      this.dateRange = [start, end]
    },
    // 查看节点容器
    viewNodeContainer(id) {
      this._fetchNodeContainerData(id)
      this.showNodeContainer = true
    },
    // 查看重启面板节点容器
    viewContainer(row) {
      this.nodeRebootContainerList = row.containers
      this.showNodeRebootContainer = true
    },
    // 查看重启面板节点容器返回
    returnBack() {
      this.nodeRebootContainer = []
      this.nodeContainerList = []
      this.showNodeContainer = false
      this.showNodeRebootContainer = false
    },
    // 查询集群节点列表
    _fetchData() {
      this.listLoading = true
      const param = this.curCluster.name
      getClusterNodes(param).then(res => {
        if (res.message.code === 0) {
          this.listLoading = false
          this.list = res.data
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 查询重启面板列表
    _fetchNodeRebootData() {
      this.listLoading = true
      const param = `${this.curCluster.name}?start_time=${this.dateRange[0].getTime()}&end_time=${this.dateRange[1].getTime()}`
      getNodeReboot(param).then(res => {
        if (res.message.code === 0) {
          this.listLoading = false
          this.nodeRebootList = res.data
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 查询特定节点上的容器列表
    _fetchNodeContainerData(nodeId) {
      this.listLoading = true
      const param = `${this.curCluster.name}/nodes/${nodeId}`
      getNodeContainer(param).then(res => {
        if (res.message.code === 0) {
          this.listLoading = false
          this.nodeContainerList = res.data
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 查询容器节点列表
    _fetchContainerNodeListData(nodeId) {
      this.listLoading = true
      const param = `${this.curCluster.name}/nodeslist`
      getContainerNodeList(param).then(res => {
        if (res.message.code === 0) {
          this.listLoading = false
          this.zombiesContainer = []
          this.loadingZoombie = true
          processArray(res.data, this)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
      // 数组异步执行操作。循环数组，查询到结果后再进行下一个查询
      async function processArray(array, myThis) {
        array.forEach(async(item, index) => {
          const param = `${myThis.curCluster.name}/zombies/${item}`
          await getZombiesContainer(param).then(res => {
            if (index === array.length - 1) {
              myThis.loadingZoombie = false
            }
            if (Object.keys(res.data).length > 0) {
              const arrObj = res.data
              let arr = []
              Object.keys(arrObj).forEach(el => {
                const subItem = arrObj[el]
                subItem.forEach(subEl => {
                  subEl.id = el
                })
                arr = arr.concat(subItem)
              })
              myThis.zombiesContainer.push.apply(myThis.zombiesContainer, arr)
            }
          })
        })
      }
    },
    // 查询僵尸容器列表
    _fetchZombiesContainerData(nodeId) {
      const param = `${this.curCluster.name}/zombies`
      getZombiesContainer(param).then(res => {
        if (res.message.code === 0) {
          const arrObj = res.data
          const arr = []
          Object.keys(arrObj).forEach(el => {
            const item = arrObj[el]
            item.id = el
            arr.push(item)
          })
          this.zombiesContainer.push(arr)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.cluster-detail {
  margin: 30px;
  .table-action {
    color: #4285f4;
  }
  .grafana-iframe {
    width: 100%;
    min-height: calc(100vh - 167px);
  }
  .click {
    color: #4285f4;
    cursor: pointer;
    font-size: 14px;
  }
  .not-allowed {
    color: #ccc;
    cursor: not-allowed;
  }
}
</style>
